home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / distutils / versionpredicate.py < prev    next >
Text File  |  2008-10-05  |  5KB  |  165 lines

  1. """Module for parsing and testing package version predicate strings.
  2. """
  3. import re
  4. import distutils.version
  5. import operator
  6.  
  7.  
  8. re_validPackage = re.compile(r"(?i)^\s*([a-z_]\w*(?:\.[a-z_]\w*)*)(.*)")
  9. # (package) (rest)
  10.  
  11. re_paren = re.compile(r"^\s*\((.*)\)\s*$") # (list) inside of parentheses
  12. re_splitComparison = re.compile(r"^\s*(<=|>=|<|>|!=|==)\s*([^\s,]+)\s*$")
  13. # (comp) (version)
  14.  
  15.  
  16. def splitUp(pred):
  17.     """Parse a single version comparison.
  18.  
  19.     Return (comparison string, StrictVersion)
  20.     """
  21.     res = re_splitComparison.match(pred)
  22.     if not res:
  23.         raise ValueError("bad package restriction syntax: %r" % pred)
  24.     comp, verStr = res.groups()
  25.     return (comp, distutils.version.StrictVersion(verStr))
  26.  
  27. compmap = {"<": operator.lt, "<=": operator.le, "==": operator.eq,
  28.            ">": operator.gt, ">=": operator.ge, "!=": operator.ne}
  29.  
  30. class VersionPredicate:
  31.     """Parse and test package version predicates.
  32.  
  33.     >>> v = VersionPredicate('pyepat.abc (>1.0, <3333.3a1, !=1555.1b3)')
  34.  
  35.     The `name` attribute provides the full dotted name that is given::
  36.  
  37.     >>> v.name
  38.     'pyepat.abc'
  39.  
  40.     The str() of a `VersionPredicate` provides a normalized
  41.     human-readable version of the expression::
  42.  
  43.     >>> print v
  44.     pyepat.abc (> 1.0, < 3333.3a1, != 1555.1b3)
  45.  
  46.     The `satisfied_by()` method can be used to determine with a given
  47.     version number is included in the set described by the version
  48.     restrictions::
  49.  
  50.     >>> v.satisfied_by('1.1')
  51.     True
  52.     >>> v.satisfied_by('1.4')
  53.     True
  54.     >>> v.satisfied_by('1.0')
  55.     False
  56.     >>> v.satisfied_by('4444.4')
  57.     False
  58.     >>> v.satisfied_by('1555.1b3')
  59.     False
  60.  
  61.     `VersionPredicate` is flexible in accepting extra whitespace::
  62.  
  63.     >>> v = VersionPredicate(' pat( ==  0.1  )  ')
  64.     >>> v.name
  65.     'pat'
  66.     >>> v.satisfied_by('0.1')
  67.     True
  68.     >>> v.satisfied_by('0.2')
  69.     False
  70.  
  71.     If any version numbers passed in do not conform to the
  72.     restrictions of `StrictVersion`, a `ValueError` is raised::
  73.  
  74.     >>> v = VersionPredicate('p1.p2.p3.p4(>=1.0, <=1.3a1, !=1.2zb3)')
  75.     Traceback (most recent call last):
  76.       ...
  77.     ValueError: invalid version number '1.2zb3'
  78.  
  79.     It the module or package name given does not conform to what's
  80.     allowed as a legal module or package name, `ValueError` is
  81.     raised::
  82.  
  83.     >>> v = VersionPredicate('foo-bar')
  84.     Traceback (most recent call last):
  85.       ...
  86.     ValueError: expected parenthesized list: '-bar'
  87.  
  88.     >>> v = VersionPredicate('foo bar (12.21)')
  89.     Traceback (most recent call last):
  90.       ...
  91.     ValueError: expected parenthesized list: 'bar (12.21)'
  92.  
  93.     """
  94.  
  95.     def __init__(self, versionPredicateStr):
  96.         """Parse a version predicate string.
  97.         """
  98.         # Fields:
  99.         #    name:  package name
  100.         #    pred:  list of (comparison string, StrictVersion)
  101.  
  102.         versionPredicateStr = versionPredicateStr.strip()
  103.         if not versionPredicateStr:
  104.             raise ValueError("empty package restriction")
  105.         match = re_validPackage.match(versionPredicateStr)
  106.         if not match:
  107.             raise ValueError("bad package name in %r" % versionPredicateStr)
  108.         self.name, paren = match.groups()
  109.         paren = paren.strip()
  110.         if paren:
  111.             match = re_paren.match(paren)
  112.             if not match:
  113.                 raise ValueError("expected parenthesized list: %r" % paren)
  114.             str = match.groups()[0]
  115.             self.pred = [splitUp(aPred) for aPred in str.split(",")]
  116.             if not self.pred:
  117.                 raise ValueError("empty parenthesized list in %r"
  118.                                  % versionPredicateStr)
  119.         else:
  120.             self.pred = []
  121.  
  122.     def __str__(self):
  123.         if self.pred:
  124.             seq = [cond + " " + str(ver) for cond, ver in self.pred]
  125.             return self.name + " (" + ", ".join(seq) + ")"
  126.         else:
  127.             return self.name
  128.  
  129.     def satisfied_by(self, version):
  130.         """True if version is compatible with all the predicates in self.
  131.         The parameter version must be acceptable to the StrictVersion
  132.         constructor.  It may be either a string or StrictVersion.
  133.         """
  134.         for cond, ver in self.pred:
  135.             if not compmap[cond](version, ver):
  136.                 return False
  137.         return True
  138.  
  139.  
  140. _provision_rx = None
  141.  
  142. def split_provision(value):
  143.     """Return the name and optional version number of a provision.
  144.  
  145.     The version number, if given, will be returned as a `StrictVersion`
  146.     instance, otherwise it will be `None`.
  147.  
  148.     >>> split_provision('mypkg')
  149.     ('mypkg', None)
  150.     >>> split_provision(' mypkg( 1.2 ) ')
  151.     ('mypkg', StrictVersion ('1.2'))
  152.     """
  153.     global _provision_rx
  154.     if _provision_rx is None:
  155.         _provision_rx = re.compile(
  156.             "([a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*)(?:\s*\(\s*([^)\s]+)\s*\))?$")
  157.     value = value.strip()
  158.     m = _provision_rx.match(value)
  159.     if not m:
  160.         raise ValueError("illegal provides specification: %r" % value)
  161.     ver = m.group(2) or None
  162.     if ver:
  163.         ver = distutils.version.StrictVersion(ver)
  164.     return m.group(1), ver
  165.